package evo.engine
{
	import flash.display.BitmapData;
	import flash.geom.Matrix;
	import flash.display.Bitmap;

	/**
	 * Abstract Post Processing class that provides basic functionality
	 * of all post processing effects framework.
	 * 
	 * It provides property [input] for effects to render themselves onto
	 * and manages updating of the effects under the system with play method.
	 * 
	 * Post processing effects are added into the engine or other post processing
	 * effect. Other effects can be added to post processing effects instead 	 
	 */
	public class AbstractPostProcessor implements IPostProcessor
	{
		protected var _input:BitmapData;
		
		private var childEffects:Array;
				
		// Set this to non-null if the processor downscales input.
		protected var scaler:Matrix;		
		protected var buffer:BitmapData;

		public function AbstractPostProcessor()
		{
			childEffects = new Array();
		}
		
		public function get input():BitmapData
		{
			return _input;
		}
		
		public function set input(input:BitmapData):void
		{
			this._input = input;
			
			// Reset input
			if(childEffects.length != 0)
			{
				for each(var efx:IDemoEffect in childEffects)
				{
					efx.output = _input;
				}
			}
		}
		
		protected function defaultInput():void
		{
			var defaultInput:BitmapData = new BitmapData(buffer.width, buffer.height, true, 0);
			input = defaultInput;
		}
		
		public function addEffect(efx:IDemoEffect):void
		{
			efx.output = _input;
			childEffects.push(efx);
		}
		
		public function removeEffect(efx:IDemoEffect):void
		{
			var tmp:Function = function(e:*, idx:int, arr:Array):Boolean {
				return e != efx;
			}
			efx.output = null;
			childEffects=childEffects.filter(tmp);
		}		
		
		public function set output(output:BitmapData):void
		{			
			this.buffer = output;
		}
		
		public function get output():BitmapData
		{
			return buffer;
		}
		
		/*
			Function: play
			
			Called every time engine wants to update its output buffers
			
			When subclassing this class, super.play(dt) should be called
			first before processing the filter
			
			Parameters:
			
				dt - time since last update to main buffer
		 */
		public function play(dt:Number):void
		{
			// Just loop through all effecs
			for each (var efx:IDemoEffect in childEffects)
				efx.play(dt);			
		}
		
		protected function copyInput():void
		{
		    // Basic copying from input
			buffer.lock();
			buffer.fillRect(buffer.rect, 0);
			buffer.draw(_input,scaler);
			buffer.unlock();
		}
		
		public function init(params:Object=null):void
		{
		}		
	}
}